#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include "vector.h"

void my_cons_fn(void* ele_ptr) {
    *(char**)ele_ptr = (char*)malloc(10 * sizeof(char));
}

// 自定义的 free 函数
void my_free_fn(void *ele_ptr) {
    if (ele_ptr != NULL) free(*((char**)ele_ptr));
}

// 自定义的 copy 函数
void my_copy_fn(const void *src, void *dst) {
    memcpy(dst, src, sizeof(char *));
}


// 测试函数
int main() {
    // 定义一个 vector，存储 char * 类型的数据
    vector v;
    vector_init(&v, sizeof(char *), my_cons_fn, my_free_fn, my_copy_fn);

    // 测试 vector 是否为空
    assert(vector_empty(&v));

    // 添加一些元素
    char *str1 = strdup("Hello");
    char *str2 = strdup("World");
    char *str3 = strdup("Vector");
    vector_push_back(&v, &str1);
    vector_push_back(&v, &str2);
    vector_push_back(&v, &str3);

    // 测试 vector 的大小和容量
    assert(vector_size(&v) == 3);
    assert(vector_capacity(&v) >= 3);

    // 测试访问元素
    char *front = VECTOR_AT(char*, &v, 0);
    printf("%s\n", front);
    assert(strcmp(front, "Hello") == 0);

    char *back = VECTOR_AT(char*, &v, 2);
    // char* back = ((char**)(&v)->data)[2];
    // char* back = *((char **)(v.data) + sizeof(char *) * 2);
    printf("%s\n", back);
    assert(strcmp(back, "Vector") == 0);

    // 测试删除最后一个元素
    vector_pop_back(&v);
    assert(vector_size(&v) == 2);
    printf("-----------------------\n");
    // 测试删除指定位置的元素
    vector_erase(&v, 0);
    assert(vector_size(&v) == 1);

    // 测试访问第一个和最后一个元素
    char *first = VECTOR_FRONT(char *, &v);
    assert(strcmp(first, "World") == 0);
    printf("%s\n", first);

    char *last = VECTOR_BACK(char *, &v);
    assert(strcmp(last, "World") == 0);
    printf("%s\n", last);

    // 测试预留存储空间
    vector_reserve(&v, 10);
    assert(vector_capacity(&v) >= 10);

    // 测试改变大小
    vector_resize(&v, 5);
    assert(vector_size(&v) == 5);

    // 测试清空 vector
    vector_clear(&v);
    assert(vector_empty(&v));

    // 测试缩小到合适大小
    for (int i = 0; i < 10; i++) {
        char* tmp = strdup("test");
        vector_push_back(&v, &tmp);
    }
    printf("size:%d capacity:%d\n", vector_size(&v), vector_capacity(&v));
    vector_shrink2fit(&v);

    printf("size:%d capacity:%d\n", vector_size(&v), vector_capacity(&v));
    printf("----------------------");
    // 释放 vector
    printf("%s\n", VECTOR_AT(char*, &v, 0));
    vector_free(&v);

    printf("All tests for vector passed successfully.\n");

    vector_init(&v, sizeof(int), NULL, NULL, NULL);
    vector_reserve(&v, 34);
    vector_resize(&v, 20);
    for (int i = 0; i < 20; i++)
    {
        int tmp = i;
        vector_set(&v, i, &tmp);
    }
    vector_erase(&v, 1);
    for (int i = 0; i < 19; i++) {
        printf("%d ", VECTOR_AT(int, &v, i));
    }
    vector_free(&v);
    printf("\n");

    return 0;
}